package org.zhxy.common.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zhxy.entity.system.ErrorLog;
import com.zhxy.entity.system.OptionalLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zhxy.common.response.ProfileResult;
import org.zhxy.common.utils.HttpContextUtil;
import org.zhxy.common.utils.IPUtil;
import org.zhxy.core.system.service.LogService;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Aspect
@Component
@Slf4j
public class LogAspect {

    @Autowired
    private LogService logService;

    @Autowired
    private OperationProperties operationProperties;


    @Pointcut("@annotation(org.zhxy.common.aop.AutomaticLog)")
    public void pointcut(){}


    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = null;
        long beginTime = System.currentTimeMillis();
        result = point.proceed();

        //获取request
        HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
        //设置ip地址
        String ip = IPUtil.getIpAddr(request);

        ProfileResult profileResult = (ProfileResult) SecurityUtils.getSubject().getPrincipal();
        String username = profileResult.getUser().getNickName();


        if(operationProperties.isOpenAopLog()){ //保存日志
            //装载系统日志类
            OptionalLog optionalLog = new OptionalLog();
            optionalLog.setUsername(username);
            optionalLog.setIp(ip);
            optionalLog.setTime(beginTime);
            logService.saveOptionalLog(point,optionalLog);
        }

        return result;
    }

    @AfterThrowing(pointcut = "pointcut()",throwing = "e")
    public void handleThrowing(JoinPoint joinPoint, Exception e) throws JsonProcessingException {
        String className = joinPoint.getTarget().getClass().getName();//获得类名
        String methodName = joinPoint.getSignature().getName();//获得方法名称
        HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
        String ipAddr = IPUtil.getIpAddr(request);//获得远程ip

        ErrorLog sysErrorLog = new ErrorLog();
        sysErrorLog.setIp(ipAddr);//远程访问主机ip
        sysErrorLog.setCreateTime(new Date());//时间
        sysErrorLog.setMessage(e.getMessage());//异常信息
        sysErrorLog.setMethod( joinPoint.getTarget() + ":" +  methodName+"()");//异常方法
        sysErrorLog.setErrorType(e.getClass().getSimpleName()+".class");//异常类型
        logService.saveErrorLog(joinPoint,sysErrorLog);
    }

}

